package cn.duxiaod.demo.thread;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 4.使用线程池创建线程
 */
public class MyThreadTest4{

    //格式化
    static SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    //AtomicInteger用来计数
    static AtomicInteger number = new AtomicInteger();

    public static void main(String[] args) {
//        createByFixdThreadPool();
//        createBySingleThreadPoolExecutor();
//        createByCachedThreadPool();
        createByScheduledThreadPool();
//        createBySingleThreadScheduledExecutor();
    }

    /**
     * 4.1固定大小的线程池
     * 使用于为了满足资源管理需求而需要限制当前线程数量的场合。使用于负载比较重的服务器。
     */
    private static void createByFixdThreadPool() {
        ExecutorService ex = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 5; i++) {
            ex.submit(()->{
                for (int j = 0; j < 10; j++) {
                    System.out.println(Thread.currentThread().getName()+":"+j);
                }
            });
        }
        ex.shutdown();
    }

    /**
     * 4.2 SingleThreadPoolExecutor :单线程池
     * 需要保证顺序执行各个任务的场景
     */
    private static void createBySingleThreadPoolExecutor() {
        ExecutorService ex = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 5; i++) {
            ex.submit(()->{
                for (int j = 0; j < 10; j++) {
                    System.out.println(Thread.currentThread().getName()+":"+j);
                }
            });
        }
        ex.shutdown();
    }

    /**
     * 4.3 CashedThreadPool(); 缓存线程池
     * 当提交任务速度高于线程池中任务处理速度时，缓存线程池会不断的创建线程
     * 适用于提交短期的异步小程序，以及负载较轻的服务器
     */
    private static void createByCachedThreadPool() {
        ExecutorService ex = Executors.newCachedThreadPool();
        for (int i = 0; i < 5; i++) {
            ex.submit(()->{
                for (int j = 0; j < 10; j++) {
                    System.out.println(Thread.currentThread().getName()+":"+j);
                }
            });
        }
        ex.shutdown();
    }

    /**
     * 4.4 ScheduledThreadPool(); 定时线程池
     */
    private static void createByScheduledThreadPool() {
        ScheduledExecutorService ex = Executors.newScheduledThreadPool(2);
        for (int i = 0; i < 5; i++) {
            ex.schedule(()->{
                for (int j = 0; j < 10; j++) {
                    System.out.println("第" + number.incrementAndGet() + "周期线程运行当前时间【" + sim.format(new Date()) + "】");
                }
            },3L,TimeUnit.SECONDS);
        }
        System.out.println("主线程运行当前时间【" + sim.format(new Date()) + "】");
        ex.shutdown();
    }

    /**
     * 4.5 SingleThreadScheduledExecutor();
     */
    private static void createBySingleThreadScheduledExecutor() {
        ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
        for (int i = 0; i < 3; i++) {
            ex.schedule(()->{
                System.out.println("第" + number.incrementAndGet() + "周期线程运行当前时间【" + sim.format(new Date()) + "】");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, 3L, TimeUnit.SECONDS);
        }
        System.out.println("主线程运行当前时间【" + sim.format(new Date()) + "】");
        ex.shutdown();
    }
}
